﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NeuralNetworks.Layers;
using System.Collections;

namespace NeuralNetworks.Neurons
{
    public abstract class Neuron
    {
        protected double _output;
        protected List<Connection> _inputs;
        protected double _biasWeight;

        public double BiasWeight
        {
            get { return _biasWeight; }
            set { _biasWeight = value; }
        }


        public List<Connection> Inputs
        {
            get { return this._inputs; }
        }

        public int InputsCount
        {
            get { return this._inputs.Count; }
        }

        public double Output
        {
            get { return this._output; }
            set { this._output = value; }
        }

        public Neuron()
        {
            _output = 0.0;
            _inputs = new List<Connection>();
            _biasWeight = 0.0;
        }

        public void AddInput(Neuron n)
        {
            if (n == null) { throw (new NeuralNetworksException()); };
            _inputs.Add(new Connection(n, 1.0));
        }

        public void AddInput(Neuron n, double w)
        {
            if (n == null) { throw (new NeuralNetworksException()); };
            _inputs.Add(new Connection(n, w));
        }

        public void RandomWeights(double min, double max, Random r)
        {
            if (r == null) { throw (new NeuralNetworksException()); };
            foreach (Connection con in _inputs)
            {
                con.Weight = (r.NextDouble() * max) + min;
            }
            _biasWeight = (r.NextDouble() * (max - min)) + min;
        }

        public void ZeroWeights()
        {
            foreach (Connection con in _inputs)
            {
                con.Weight = 0;
            }
            _biasWeight = 0;
        }

        public abstract void Compute();

        public void AddInputs(Layer l)
        {
            if (l == null) { throw (new NeuralNetworksException()); };
            foreach (Neuron n in l.Neurons)
            {
                AddInput(n);
            }
        }
    }
}
